package com.snailhd.cloud.account.authorization.filter;

import com.alibaba.fastjson.JSONObject;
import com.snailhd.cloud.account.spi.TokenService;
import com.snailhd.cloud.account.authorization.annotation.Token;
import com.snailhd.cloud.account.authorization.exception.TokenException;
import com.snailhd.common.entity.IResult;
import com.snailhd.common.enums.RespSubCodeEnum;
import com.snailhd.common.util.web.ParserParamUtil;
import org.springframework.core.MethodParameter;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletRequest;

/**
 * @author hd
 */
public class TokenResovler implements HandlerMethodArgumentResolver {

	private static final String PARAMS_TOKEN = "token";

	private static final String HEADER_TOKEN = "authorization";

    TokenService tokenService;

    public TokenResovler() {
    }

    public TokenResovler(TokenService tokenService) {
        this.tokenService = tokenService;
    }

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        //返回是否使用给定的注释类型声明参数。
		return parameter.hasParameterAnnotation(Token.class);
	}

	@Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        try{
            String token = getTokenByHeader(webRequest);

            if(StringUtils.isEmpty(token)) {
                throw new TokenException();
            }

//            TokenService tokenService = SpringContextUtil.getBean(TokenService.class);
            IResult iresult= tokenService.verifyToken(token);
            if(iresult.isFail()) {
                throw new TokenException(iresult.getSubMsg());
            }
            Object account = iresult.getData();

//        String type = Conventions.getVariableNameForParameter(parameter);
//        String name = parameter.getParameterName();
            Class clazz = parameter.getParameterType();
            Object obj = null;

            if(clazz == account.getClass()) {
                obj =  account;
            }

            return obj;

        }catch (Exception e){
            throw new TokenException(RespSubCodeEnum.PALCE_LOGIN.generalSubMsg());
        }


	}


	/**
	 * @Author hd
	 * @Description 从消息头中获取token
	 * @Date 2019-06-08 22:58
	 * @Param [webRequest]
	 * @return java.lang.String
	 **/
    private String getTokenByHeader(NativeWebRequest webRequest) {
        return webRequest.getHeader(HEADER_TOKEN);
    }

    /**
     * @Author hd
     * @Description 从参数中获取token
     * @Date 2019-06-08 22:57
     * @Param [webRequest]
     * @return java.lang.String
     **/
    private String getTokenByParams(NativeWebRequest webRequest) {
        String token = null;
        HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
        JSONObject jsonObj = ParserParamUtil.getParamFromRequest2JSONObj(servletRequest);
        if(jsonObj!=null){
            token = jsonObj.getString(PARAMS_TOKEN);
        }
        return token;
    }

	

}
